﻿using Microsoft.Extensions.Logging;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Framework.LinkTrackingLog.AI_Deepseek
{
    /// <summary>
    /// 方法监控服务接口
    /// 定义监控系统的核心能力
    /// </summary>
    public interface IMethodMonitoringService
    {
        /// <summary>
        /// 开始监控一个方法
        /// </summary>
        /// <param name="methodName">方法全名</param>
        /// <returns>返回IDisposable，当释放时表示方法执行结束</returns>
        IDisposable BeginMonitor(string methodName);

        /// <summary>
        /// 获取所有执行记录
        /// </summary>
        IEnumerable<MethodExecutionRecord> GetExecutionRecords();
    }

    /// <summary>
    /// 方法执行记录实体
    /// 记录单个方法的执行情况
    /// </summary>
    public class MethodExecutionRecord
    {
        /// <summary>
        /// 方法全名
        /// </summary>
        public string MethodName { get; set; }
        /// <summary>
        /// 执行耗时(毫秒)
        /// </summary>
        public long ElapsedMilliseconds
        {
            get
            {
                return (long)(EndTime - StartTime).TotalMilliseconds;
            }
        }
        /// <summary>
        /// 开始时间
        /// </summary>
        public DateTime StartTime { get; set; }
        /// <summary>
        /// 结束时间
        /// </summary>
        public DateTime EndTime { get; set; }
        /// <summary>
        /// 子方法调用记录
        /// </summary>
        public List<MethodExecutionRecord> Children { get; set; } = []; 
    }

    /// <summary>
    /// 方法监控服务实现
    /// 核心功能：记录方法调用链和时间消耗
    /// </summary>
    public class MethodMonitoringService : IMethodMonitoringService
    {
        private readonly ILogger<MethodMonitoringService> _logger;

        // 使用AsyncLocal保证异步调用链中的上下文正确传递
        private readonly AsyncLocal<MethodExecutionRecord> _currentRecord = new AsyncLocal<MethodExecutionRecord>();

        // 存储所有根节点记录(入口方法)
        private readonly ConcurrentBag<MethodExecutionRecord> _rootRecords = new ConcurrentBag<MethodExecutionRecord>();

        public MethodMonitoringService(ILogger<MethodMonitoringService> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 开始监控一个方法
        /// </summary>
        public IDisposable BeginMonitor(string methodName)
        {
            // 创建新的执行记录
            var record = new MethodExecutionRecord
            {
                MethodName = methodName,
                StartTime = DateTime.UtcNow
            };

            // 获取当前上下文中的父记录(可能为null)
            var parent = _currentRecord.Value;

            if (parent != null)
            {
                // 如果有父记录，将当前记录添加为子记录
                parent.Children.Add(record);
            }
            else
            {
                // 如果没有父记录，说明是入口方法，添加到根记录集合
                _rootRecords.Add(record);
            }

            // 设置当前记录为上下文记录
            _currentRecord.Value = record;

            // 返回一个Disposable对象，当释放时表示方法执行结束
            return new DisposableAction(() =>
            {
                // 记录结束时间和耗时
                record.EndTime = DateTime.UtcNow;

                // 记录日志
                _logger.LogInformation($"方法 {methodName} 执行时间: {record.ElapsedMilliseconds}ms");

                // 恢复父记录为当前上下文
                _currentRecord.Value = parent;
            });
        }

        /// <summary>
        /// 获取所有执行记录
        /// </summary>
        public IEnumerable<MethodExecutionRecord> GetExecutionRecords()
        {
            return _rootRecords.ToList();
        }

        /// <summary>
        /// 可释放的Action包装器
        /// 用于在using块结束时执行记录结束逻辑
        /// </summary>
        private class DisposableAction : IDisposable
        {
            private readonly Action _action;

            public DisposableAction(Action action)
            {
                _action = action;
            }

            public void Dispose()
            {
                _action();
            }
        }
    }
}
